/*
** kbdedit.c
**
** Pictor, Version 1.51, Copyright (c) 1992-94 SoftCircuits
** Redistributed by permission.
*/

#include <ctype.h>
#include <string.h>
#include "pictor.h"

#define UPDATE_NOUPDATE 0
#define UPDATE_CURSOR	1
#define UPDATE_EDIT		2


int _PL_editfill = '\xFA';
int _PL_tabendedit = FALSE;

#define MAX_STRLEN  128
static char localbuff[MAX_STRLEN + 1];

/*
** Allows the user to edit the given string. Initially, the string
** is selected. If the user types new characters, they replace the
** selected text. If the user presses an edit key (left, right,
** backspace, etc), the original string is edited. Returns TRUE if
** the user pressed Enter, returns FALSE and buffer is unchanged if
** the user pressed escape
*/
int kbdedit(char *buffer,int row,int col,int width,
	int maxlen,COLORSTRUCT *colors)
{
	int i,key,pos,len,retval = 0;
	int leftcol = 0,update = UPDATE_EDIT,done = FALSE,first_time = TRUE;

	strcpy(localbuff,buffer);
	pos = len = strlen(localbuff);

	if(maxlen > MAX_STRLEN)
		maxlen = MAX_STRLEN;

	pushcurs();
	showcurs(TRUE);

	while(!done) {
		if(update != UPDATE_NOUPDATE) {
			if(pos <= leftcol) {
				leftcol = (pos > 0) ? (pos - 1) : pos;
				update = UPDATE_EDIT;
			}
			else if(pos >= (leftcol + width)) {
				leftcol = ((pos - width) + 1);
				update = UPDATE_EDIT;
			}
			if(update == UPDATE_EDIT) {
				setvpos(row,col);
				for(i = 0;i < width;i++) {
					if((leftcol + i) < len) {
						vcolor((first_time) ? colors->select : colors->normal);
						vputc(localbuff[i + leftcol]);
					}
					else {
						vcolor(colors->normal);
						vputc((char)_PL_editfill);
					}
				}
			}
			setcurs(row,col + (pos - leftcol));
			update = UPDATE_NOUPDATE;
		}
		switch(key = kbdread()) {
			case HOME_KEY:
				if(pos > 0) {
					pos = 0;
					update = UPDATE_CURSOR;
				}
				break;
			case END_KEY:
				if(pos < len) {
					pos = len;
					update = UPDATE_CURSOR;
				}
				break;
			case LEFT_KEY:
				if(pos > 0) {
					pos--;
					update = UPDATE_CURSOR;
				}
				else beep();
				break;
			case RIGHT_KEY:
				if(pos < len) {
					pos++;
					update = UPDATE_CURSOR;
				}
				else beep();
				break;
			case BACKSPACE_KEY:
				if(pos > 0) {
					pos--;
					memmove(localbuff+pos,localbuff+pos+1,len-pos);
					len--;
					update = UPDATE_EDIT;
				}
				else beep();
				break;
			case DELETE_KEY:
				if(pos < len) {
					memmove(localbuff+pos,localbuff+pos+1,len-pos);
					len--;
					update = UPDATE_EDIT;
				}
				else beep();
				break;
			case TAB_KEY:
				if(_PL_tabendedit) {
					strcpy(buffer,localbuff);
					retval = -1;
					done = TRUE;
				}
				else beep();
				break;
			case SHIFTTAB_KEY:
				if(_PL_tabendedit) {
					strcpy(buffer,localbuff);
					retval = -2;
					done = TRUE;
				}
				else beep();
				break;
			case ESCAPE_KEY:
				retval = FALSE;
				done = TRUE;
				break;
			case ENTER_KEY:
				strcpy(buffer,localbuff);
				retval = TRUE;
				done = TRUE;
				break;
			case F1_KEY:
				if(_PL_helpfunc != NULL)
					_PL_helpfunc(_PL_helpcontext);
				else
					beep();
				continue;
			default:
				key = key & 0xFF;
				if(isprint(key)) {
					if(first_time) { /* typing replaces selected text */
						leftcol = pos = len = 0;
						localbuff[0] = '\0';
					}
					if(len < maxlen) {
						len++;
						memmove(localbuff+pos+1,localbuff+pos,len - pos);
						localbuff[pos] = (char)key;
						pos++;
						update = UPDATE_EDIT;
					}
					else beep();
				}
				else {
					beep();
					continue;
				}
				break;
		}
		if(first_time) {
			first_time = FALSE;
			setvpos(row,col);
			vrepa(colors->normal,width);
		}
	}
	popcurs();

	return(retval);

} /* kbdedit */
